package org.rcy.framework.file.excel;

import com.alibaba.excel.util.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;


/**
 * @author 吴康桥
 * @Description
 * @date 2022/12/12 15:31
 */


public class PoiExcelService{

	public List<Map<String,String>> readExcel(InputStream inputStream, Class clazz) throws Exception {
		// 创建表格对象
		XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
		//有多少个sheet
		int sheets = workbook.getNumberOfSheets();
		Field[] fields = clazz.getDeclaredFields();
		CountDownLatch countDownLatch = new CountDownLatch(sheets);
		List<Map<String,String>> resList = new ArrayList<>();
		for (int i = 0; i < sheets; i++) {
			//解析每个sheet的数据
			new Thread(new ReadExcelThread(i) {
				@Override
				public void run() {
					Sheet sheet = workbook.getSheetAt(getIndex());
					//获取多少行
					int rows = sheet.getPhysicalNumberOfRows();
					Map<String,String> map = null;
					//注意：第0为表头，第1行开始解析数据
					for (int currentRow = 1; currentRow < rows; currentRow++) {
						map = new HashMap<>();
						Row row = sheet.getRow(currentRow);
						parseCellData(row,resList,fields,map);
						if(map.size() > 0) {
							resList.add(map);
						}
					}
					countDownLatch.countDown();
				}
			}).start();
		}
		// 所有数据解析完成后
		countDownLatch.await();
		return resList;
	}

	/**
	 * 获取表格数据
	 *
	 * @return
	 */
	private void parseCellData(Row row, List<Map<String,String>> resList, Field[] fields, Map<String,String> map){
			for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum++) {
				Cell cell = row.getCell(cellNum);
				Object value = null;
				if(cell == null || StringUtils.isBlank((String)(value = getCellValue(cell)))){
					continue;
				}
				map.put(fields[cellNum].getName(),value+"");
			}
	}

	/**
	 * 解析数据类型
	 *
	 * @param cell
	 * @return
	 */
	private Object getCellValue(Cell cell) {
		//1.获取到单元格的属性类型
		CellType cellType = cell.getCellType();
		//2.根据单元格数据类型获取数据
		Object value = null;
		switch (cellType) {
			case STRING:
				value = cell.getStringCellValue();
				break;
			case BOOLEAN:
				value = cell.getBooleanCellValue();
				break;
			case NUMERIC:
				if (DateUtil.isCellDateFormatted(cell)) {
					//日期格式
					value = cell.getDateCellValue();
				} else {
					//数字,poi解析的数值都是double类型
					value = cell.getNumericCellValue();
				}
				break;
			case FORMULA:
				//公式
				value = cell.getCellFormula();
				break;
			default:
				break;
		}
		return value;
	}


	public int writeExcel(int index,Class clazz,List<Map<String,String>> datas,Sheet sheet) throws IOException {
		return this.writeExcel(index, clazz, datas, sheet,null);
	}

	public int writeExcel(int index,Class clazz,List<Map<String,String>> datas,Sheet sheet,StyleCallBack styleCallBack) throws IOException {
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < datas.size(); i++) {
			Row row = sheet.createRow(index);
			row.setHeightInPoints(22.0f);
			for (int j = 0; j < fields.length; j++) {
				row.createCell(j).setCellValue(datas.get(i).get(fields[j].getName()));
			}
			((SXSSFSheet) sheet).flushRows();
			index++;
		}
		if(styleCallBack != null) {
			styleCallBack.callBack(sheet);
		}
		return index;
	}
}
